/**
 * Database 类 - 负责数据库的核心操作
 * 
 * @class Database
 */

import Model from './Model';
import Utils from './Utils';
import Query from './Query';
import EventEmitter from './EventEmitter';

class Database extends EventEmitter {
  /**
   * 构造函数
   * @param {Config} config - 数据库配置
   */
  constructor(config) {
    super();
    this.config = config;
    this.isOpen = false;
    this.collections = new Map(); // 存储集合对象
    this.transactionQueue = []; // 事务队列
    this.isProcessingTransaction = false;
  }
  
  /**
   * 初始化数据库
   */
  async init() {
    try {
      // 初始化存储（文件系统或内存）
      this.storage = await Utils.initStorage(this.config);
      
      // 加载已定义的模型
      this.loadModels();
      
      // 标记数据库为已打开
      this.isOpen = true;
      
      console.log(`ETSDB: Database '${this.config.name}' initialized successfully`);
    } catch (error) {
      console.error('ETSDB: Failed to initialize database:', error);
      throw error;
    }
  }
  
  /**
   * 加载已定义的模型
   */
  loadModels() {
    const models = Model.getAllModels();
    models.forEach(model => {
      this.getCollection(model.name);
    });
  }
  
  /**
   * 获取或创建集合
   * @param {string} name - 集合名称
   * @returns {Collection} 集合对象
   */
  getCollection(name) {
    if (!this.collections.has(name)) {
      const collection = {
        name,
        model: Model.getModel(name)
      };
      this.collections.set(name, collection);
    }
    return this.collections.get(name);
  }
  
  /**
   * 创建文档对象
   * @param {string} collectionName - 集合名称
   * @param {Object} data - 文档数据
   * @returns {Object} 文档对象
   */
  create(collectionName, data) {
    const collection = this.getCollection(collectionName);
    if (!collection.model) {
      throw new Error(`Model '${collectionName}' is not defined`);
    }
    
    // 使用模型验证和创建文档
    return collection.model.create(data);
  }
  
  /**
   * 保存文档到数据库
   * @param {string|Object} collectionNameOrDoc - 集合名称或文档对象
   * @param {Object} [data] - 文档数据（当第一个参数是集合名称时）
   * @returns {Promise<Object>} 保存后的文档
   */
  async save(collectionNameOrDoc, data) {
    let collectionName;
    let doc;
    
    if (typeof collectionNameOrDoc === 'string') {
      collectionName = collectionNameOrDoc;
      doc = this.create(collectionName, data);
    } else {
      // 从文档对象中获取集合名称
      collectionName = doc.collectionName || doc.constructor.modelName;
      doc = collectionNameOrDoc;
    }
    
    if (!collectionName) {
      throw new Error('Collection name is required');
    }
    
    return await this.executeTransaction(async () => {
      // 保存文档到存储
      await this.storage.saveDocument(collectionName, doc);
      
      // 触发文档保存事件
      this.emit('documentSaved', { collection: collectionName, document: doc });
      
      return doc;
    });
  }
  
  /**
   * 查找文档
   * @param {string} collectionName - 集合名称
   * @param {Object} query - 查询条件
   * @param {Object} options - 查询选项（如排序、分页等）
   * @returns {Promise<Array>} 查询结果数组
   */
  async find(collectionName, query = {}, options = {}) {
    const collection = this.getCollection(collectionName);
    
    // 构建查询
    const queryObj = new Query(query, options);
    
    // 从存储中查询文档
    const documents = await this.storage.findDocuments(collectionName, queryObj);
    
    // 如果有模型，将原始数据转换为模型实例
    if (collection.model) {
      return documents.map(doc => collection.model.fromJSON(doc));
    }
    
    return documents;
  }
  
  /**
   * 根据ID查找单个文档
   * @param {string} collectionName - 集合名称
   * @param {string} id - 文档ID
   * @returns {Promise<Object|null>} 文档对象或null
   */
  async findById(collectionName, id) {
    const collection = this.getCollection(collectionName);
    const doc = await this.storage.findDocumentById(collectionName, id);
    
    if (doc && collection.model) {
      return collection.model.fromJSON(doc);
    }
    
    return doc;
  }
  
  /**
   * 更新文档
   * @param {string} collectionName - 集合名称
   * @param {Object} query - 查询条件
   * @param {Object} update - 更新操作
   * @returns {Promise<number>} 更新的文档数量
   */
  async update(collectionName, query, update) {
    return await this.executeTransaction(async () => {
      const result = await this.storage.updateDocuments(collectionName, query, update);
      
      // 触发更新事件
      this.emit('documentsUpdated', { 
        collection: collectionName, 
        query, 
        update, 
        count: result 
      });
      
      return result;
    });
  }
  
  /**
   * 删除文档
   * @param {string} collectionName - 集合名称
   * @param {Object} query - 查询条件
   * @returns {Promise<number>} 删除的文档数量
   */
  async delete(collectionName, query) {
    return await this.executeTransaction(async () => {
      const result = await this.storage.deleteDocuments(collectionName, query);
      
      // 触发删除事件
      this.emit('documentsDeleted', { 
        collection: collectionName, 
        query, 
        count: result 
      });
      
      return result;
    });
  }
  
  /**
   * 执行事务
   * @param {Function} operation - 事务操作函数
   * @returns {Promise<any>} 操作结果
   */
  async executeTransaction(operation) {
    return new Promise((resolve, reject) => {
      // 将操作添加到事务队列
      this.transactionQueue.push({ operation, resolve, reject });
      
      // 如果当前没有正在处理的事务，则开始处理
      if (!this.isProcessingTransaction) {
        this.processNextTransaction();
      }
    });
  }
  
  /**
   * 处理下一个事务
   */
  async processNextTransaction() {
    if (this.transactionQueue.length === 0) {
      this.isProcessingTransaction = false;
      return;
    }
    
    this.isProcessingTransaction = true;
    const { operation, resolve, reject } = this.transactionQueue.shift();
    
    try {
      // 开始事务
      await this.storage.beginTransaction();
      
      // 执行操作
      const result = await operation();
      
      // 提交事务
      await this.storage.commitTransaction();
      
      resolve(result);
    } catch (error) {
      // 回滚事务
      try {
        await this.storage.rollbackTransaction();
      } catch (rollbackError) {
        console.error('ETSDB: Failed to rollback transaction:', rollbackError);
      }
      
      reject(error);
    } finally {
      // 继续处理下一个事务
      this.processNextTransaction();
    }
  }
  
  /**
   * 监听集合变化
   * @param {string} collectionName - 集合名称
   * @param {Function} callback - 回调函数
   * @returns {Object} 订阅对象，包含unsubscribe方法
   */
  watch(collectionName, callback) {
    const eventName = `change:${collectionName}`;
    this.on(eventName, callback);
    
    // 设置存储监听器
    this.storage.watchCollection(collectionName, (changes) => {
      this.emit(eventName, changes);
    });
    
    return {
      unsubscribe: () => {
        this.off(eventName, callback);
        this.storage.unwatchCollection(collectionName, callback);
      }
    };
  }
  
  /**
   * 关闭数据库连接
   */
  close() {
    if (this.isOpen) {
      this.storage.close();
      this.isOpen = false;
      console.log(`ETSDB: Database '${this.config.name}' closed`);
    }
  }
  
  /**
   * 获取数据库统计信息
   * @returns {Promise<Object>} 统计信息
   */
  async getStats() {
    return await this.storage.getStats();
  }
}

export default Database;